/*
RAII
Rust 的变量不只是在栈中保存数据：它们也占有资源，比如 `Box<T>`占有堆(heap)中的内存。
Rust强制实行RAII(Resource Acquisition Is Initialization, 资源获取即初始化)，所以
任何对象在离开作用域时，它的析构函数(destructor)就被调用，然后它占有的资源就被释放。
这种行为避免了资源泄漏(resource leak)，所以你再也不用手动释放内存或者担心内存泄漏(memory leak)
*/

fn create_box() {
    // 在堆上分配一个整型数据
    let _xbox1 = Box::new(3i32);

    // `_xbox1` 在这里被销毁，内存得到释放
}

// Rust 中的析构函数概念是通过 `Drop` trait提供的。
// 当资源离开作用域，就调用析构函数。
// 只要为那些需要自己的析构函数逻辑的类型实现就可以。
struct ToDrop;

impl Drop for ToDrop {
    fn drop(&mut self) {
        println!("ToDrop is being dropped");
    }
}

fn main() {

    let x = ToDrop;
    println!("Made a ToDrop!");

    // 在堆上分配一个整型数据
    let _xbox2 = Box::new(5i32);

    // 嵌套作用域
    {
        // 在堆上分配一个整型数据
        let _xbox3 = Box::new(4i32);

        // `_xbox3` 在这里被销毁，内存得到释放
    }

    // 创建一个大堆 box
    // 完全不需要手动释放内存
    for _ in 0u32..1_000 {
        create_box();
    }

    // `_xbox2` 在这里被销毁，内存得到释放

    // `x` 离开作用域，析构函数被调用
}